﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
using Pub;
using WORD = System.UInt16;
using DWORD = System.UInt32;
using BYTE = System.Byte;
using ULONGLONG = System.UInt64;
using System.Reflection;
using System.Runtime.InteropServices;
//using Pub.DB;
using System.Threading;
using JT_PE;

namespace LZQXT.Test.Forms.PE
{

    public partial class FPEMain : Form
    {
        string sFileName = "";                          //文件名
        byte[] pe_byte_array;                           //文件内容
        int f_Len = 0;                                  //文件长度
        CPE pe = new CPE();
        int tv_pe_index = 0;                            //选中的菜单id
        List<Button> lstBtn = new List<Button>();       //区段表做略图

        Bitmap B;
        Graphics g;

        TreeNodePE tvNode;

        public FPEMain()
        {
            InitializeComponent();
        }

        private void btnOpen_Click(object sender, EventArgs e)
        {
            int i_btn = 0;
            if (sender is ToolStripButton) i_btn = Convert.ToInt16(((ToolStripButton)sender).Tag);

            switch (i_btn)
            {
                case 1:                  //open
                    CDebug.EnterMethod("打开文件");
                    OpenFileDialog opendlg = new OpenFileDialog();
                    opendlg.Filter = "pe文件(*.exe;*.dll;*.ocx)|*.exe;*.dll;*.ocx|所有文件(*.*)|*.*";
                    if (opendlg.ShowDialog() == DialogResult.OK)
                    {
                        sFileName = opendlg.FileName;
                        CDebug.Send(sFileName);
                        lv_info.Items.Clear();                  //清除列表中的数据
                        tv_info.Nodes.Clear();                  //清除树中的信息
                        tv_pe.Nodes[3].Nodes.Clear();           //清除区块表树目录
                        tv_pe.Nodes[4].Nodes.Clear();           //清除输入表树目录
                        tv_pe.Nodes[5].Nodes.Clear();           //清除输出表树目录
                        tv_pe.Nodes[6].Nodes.Clear();           //清除资源树目录
                        
                        openFile();                             //读入文件
                        
                        getDosHeader();                         //解析DOS_Header

                        getFileHeader();                        //解析File_Header

                        getOptionalHeader();                    //解析Optional_Header

                        getDataDirectory();                     //解析数据目录

                        getSectionHeader();                     //解析区块表

                        refDataView();                          //显示各区块长度
                        
                        lv_info.AutoResizeColumns(ColumnHeaderAutoResizeStyle.ColumnContent);   //自动调整列宽
                        
                        tv_pe.SelectedNode = tv_pe.Nodes[0];    //选中第一个菜单
                    }
                    CDebug.ExitMethod("打开文件");
                    break;
                case 2:                                         //另存
                    if (pe.FILE_LENGTH == 0) return;
                    FPESaveAS f_save_as = new FPESaveAS();
                    f_save_as.ShowDialog(pe);
                    break;
                case 100:
                    readHtmlFile();
                    break;
            }
        }

        /// <summary>
        /// 初始化界面设置
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void FPEMain_Load(object sender, EventArgs e)
        {
            lv_info.Dock = DockStyle.Fill;
            tv_info.Dock = DockStyle.Fill;
            //tboxHex.Dock = DockStyle.Fill;

            tv_info.Visible = false;
            tboxHex.Visible = false;
            splitter2.Visible = false;
            splitter3.Visible = false;
            btnReadHtml.Visible = false;

            panel1.Height = 22;

            B = new Bitmap(panel1.Width, panel1.Height);
            g = Graphics.FromImage(B);

            //创建树菜单
            TreeNodePE node1 = new TreeNodePE("MS_DOS头", 1, 1);
            TreeNodePE node2 = new TreeNodePE("PE头", 1, 1);
            TreeNodePE node3 = new TreeNodePE("数据目录表", 1, 1);
            TreeNodePE node4 = new TreeNodePE("区块表", 1, 1);
            TreeNodePE node5 = new TreeNodePE("输入表", 1, 1);
            TreeNodePE node6 = new TreeNodePE("输出表", 1, 1);
            TreeNodePE node7 = new TreeNodePE("资源", 1, 1);

            node1.Tag = 100;
            node2.Tag = 200;
            node3.Tag = 300;
            node4.Tag = 400;
            node5.Tag = 500;
            node6.Tag = 600;
            node7.Tag = 700;

            tv_pe.Nodes.Clear();
            tv_pe.Nodes.Add(node1);
            tv_pe.Nodes.Add(node2);
            tv_pe.Nodes.Add(node3);
            tv_pe.Nodes.Add(node4);
            tv_pe.Nodes.Add(node5);
            tv_pe.Nodes.Add(node6);
            tv_pe.Nodes.Add(node7);
        }

        /// <summary>
        /// 打开文件
        /// </summary>
        private void openFile()
        {
            CDebug.EnterMethod("读取文件");
            FileStream fs = File.Open(sFileName, FileMode.Open, FileAccess.Read);
            FileInfo fi = new FileInfo(sFileName);
            f_Len = (int)fi.Length;
            pe_byte_array = new byte[f_Len];
            int nBytesRead = fs.Read(pe_byte_array, 0, f_Len);
            //pe_byte_array = ByteArray;
            fs.Close();                                         //关闭文件
            Thread.Sleep(300);                                  //等待文件读取结束

            pe.FILE_LENGTH = f_Len;
            pe.FILE_ARRAY = pe_byte_array;

            tboxHex.Text = "";
            StringBuilder sb = new StringBuilder();
            string s1 = "";
            string s_Empty = " ";                                           //"_" or " " Char(0)占位字符
            /*
            for (int i = 0; i < nBytesRead; i++)
            {
                sb.Append(pe_byte_array[i].ToString("X2") + " ");               //16进制显示

                int j = pe_byte_array[i];
                if (j == 0) s1 += s_Empty;                                  //Char(0) 显示为“_”
                else if (j >= 10 && j <= 13) s1 += s_Empty;                 //处理Char(10)~Char(13)间的字符，不处理时显示为换行
                else s1 += Convert.ToChar(j);

                if ((i + 1) % 08 == 0) sb.Append(" ");                      //隔10字节加一个空格


                if ((i + 1) % 16 == 0)                                      //换行
                {
                    //s1 = s1.Replace("\r", "_");                           //替换回车 显示为“_”
                    //s1 = s1.Replace("\n", "_");                           //替换换行 显示为“_”

                    sb.Append(s1);
                    sb.Append("\n");
                    s1 = "";
                }
            }
            */
            tboxHex.Text = sb.ToString();
            CDebug.ExitMethod("读取文件");
        }

        /// <summary>
        /// 解析dos头
        /// </summary>
        private void getDosHeader()
        {
            CDebug.EnterMethod("解析Dos头");
            try
            {
                //给DOS头结构体赋值
                CPub.BytesToStuct(pe_byte_array, pe.DOS_HEADER, 0);         //index从0开始
                pe.FILE_HEADER_START = pe.DOS_HEADER.e_lfanew;              //获取pe头开始位置

                int i_index = 0;
                ListViewGroup lvGroup = new ListViewGroup("MS_DOS HEADER");
                lv_info.Groups.Add(lvGroup);
                ListViewItem lvitem = null;
                for (int i = 0; i < pe.DOS_HEADER_TXT.Length; i++)
                {
                    lvitem = new ListViewItem();
                    lvitem.Group = lvGroup;
                    lvitem.Text = pe.DOS_HEADER_TXT[i];
                    string s1 = "";
                    for (int j = 0; j < pe.DOS_HEADER_LEN[i]; j++)
                    {
                        s1 += pe_byte_array[i_index].ToString("X2");
                        i_index++;
                    }
                    //s1 = CPub.HexReversal(s1);                                              //反转字符串
                    lvitem.SubItems.Add(CPub.insertStrStepN(s1.Trim(), 4, " "));            //每4字节用空格分隔
                    lvitem.SubItems.Add(pe.DOS_HEADER_OTH[i]);                              //说明
                    lvitem.Tag = s1.Trim();
                    lv_info.Items.Add(lvitem);
                }

                CDebug.Send(Convert.ToString(pe.DOS_HEADER.e_lfanew, 16));
            }
            catch (System.Exception ex)
            {
            	CDebug.SendError(ex.ToString());
            }
            CDebug.ExitMethod("解析Dos头");
        }

        /// <summary>
        /// 解析pe头 File_Header部分
        /// </summary>
        private void getFileHeader()
        {
            CDebug.EnterMethod("解析File_Header");
            try
            {

                DWORD i_index = pe.FILE_HEADER_START + 4;   //偏移4字节
                CDebug.Send("File_Header起始位置：" + i_index.ToString("X"));

                //给结构体赋值
                CPub.BytesToStuct(pe_byte_array, pe.FILE_HEADER, (int)(pe.FILE_HEADER_START + 4));
                pe.OPTIONAL_HEADER_START = pe.FILE_HEADER_START + 4 + (DWORD)Marshal.SizeOf(pe.FILE_HEADER);    //Optional_Header起始位置
                //CDebug.Send(pe.FILE_HEADER.Machine.ToString("X"));

                ListViewGroup lvGroup = new ListViewGroup("FILE HEADER");
                lv_info.Groups.Add(lvGroup);
                ListViewItem lvitem = null;
                for (int i = 0; i < pe.FILE_HEADER_TXT.Length; i++)
                {
                    lvitem = new ListViewItem();
                    lvitem.Group = lvGroup;
                    lvitem.Text = pe.FILE_HEADER_TXT[i];
                    string s1 = "";
                    for (int j = 0; j < pe.FILE_HEADER_LEN[i]; j++)
                    {
                        s1 += pe_byte_array[i_index].ToString("X2");
                        i_index++;
                    }
                    s1 = CPub.HexReversal(s1);                                              //反转字符串
                    lvitem.SubItems.Add(CPub.insertStrStepN(s1.Trim(), 4, " "));            //每4字节用空格分隔
                    lvitem.SubItems.Add(pe.FILE_HEADER_OTH[i]);                             //说明
                    lvitem.Tag = s1.Trim();
                    lv_info.Items.Add(lvitem);
                }

            }
            catch (Exception ex)
            {
                CDebug.SendError(ex.ToString());
            }
            CDebug.ExitMethod("解析File_Header");
        }

        /// <summary>
        /// 解析pe头 Optional_Header pe头扩展部分
        /// </summary>
        private void getOptionalHeader()
        {
            CDebug.EnterMethod("解析Optional_Header");
            try
            {
                DWORD i_index = pe.OPTIONAL_HEADER_START;
                CDebug.Send("Optional_Header起始位置：" + i_index.ToString("X"));
                
                CPub.BytesToStuct(pe_byte_array, pe.OPTIONAL_HEADER, (Int32)pe.OPTIONAL_HEADER_START);
                pe.DATA_DIRECTORY_START = pe.OPTIONAL_HEADER_START + (DWORD)Marshal.SizeOf(pe.OPTIONAL_HEADER);     //Data_Directory起始位置

                ListViewGroup lvGroup = new ListViewGroup("OPTIONAL HEADER");
                lv_info.Groups.Add(lvGroup);
                ListViewItem lvitem = null;
                for (int i = 0; i < pe.OPTIONAL_HEADER_TXT.Length; i++)
                {
                    lvitem = new ListViewItem();
                    lvitem.Group = lvGroup;
                    lvitem.Text = pe.OPTIONAL_HEADER_TXT[i];
                    string s1 = "";
                    for (int j = 0; j < pe.OPTIONAL_HEADER_LEN[i]; j++)
                    {
                        s1 += pe_byte_array[i_index].ToString("X2");
                        i_index++;
                    }
                    s1 = CPub.HexReversal(s1);                                      //反转字符串
                    lvitem.SubItems.Add(CPub.insertStrStepN(s1.Trim(), 4, " "));    //每4字节用空格分隔
                    lvitem.SubItems.Add(pe.OPTIONAL_HEADER_OTH[i]);                 //说明
                    lvitem.Tag = s1.Trim();
                    lv_info.Items.Add(lvitem);

                }
            }
            catch (Exception ex)
            {
                CDebug.SendError(ex.ToString());
            }
            CDebug.ExitMethod("解析Optional_Header");
        }

        /// <summary>
        /// 解析数据目录
        /// </summary>
        private void getDataDirectory()
        {
            CDebug.EnterMethod("解析数据目录");
            try
            {

                DWORD i_index = pe.DATA_DIRECTORY_START;
                CDebug.Send("数据目录起始位置：" +  i_index.ToString("X"));

                //给结构体赋值
                DWORD d_index = pe.DATA_DIRECTORY_START;
                for (int i = 0; i < pe.DATA_DIRECTORY_TIT.Length; i++)
                {
                    pe.DATA_DIRECTORY[i] = new CPE.IMAGE_DATA_DIRECTORY();                  //实例化对象
                    CPub.BytesToStuct(pe_byte_array, pe.DATA_DIRECTORY[i], (Int32)d_index);
                    d_index += (DWORD)Marshal.SizeOf(pe.DATA_DIRECTORY[i]);
                }
                pe.SECTION_HEADER_START = pe.DATA_DIRECTORY_START + (DWORD)pe.DATA_DIRECTORY_TIT.Length * (DWORD)Marshal.SizeOf(pe.DATA_DIRECTORY[0]);   //区块表起始位置
                //CDebug.Send(pe.SECTION_HEADER_START.ToString("X"));

                for (int i = 0; i < pe.DATA_DIRECTORY_TIT.Length; i++)
                {
                    ListViewGroup lvGroup = new ListViewGroup("DATA DIRECTORY");
                    lv_info.Groups.Add(lvGroup);
                    ListViewItem lvitem = null;

                    lvGroup = new ListViewGroup(pe.DATA_DIRECTORY_TIT[i]);
                    lv_info.Groups.Add(lvGroup);
                    for (int k = 0; k < pe.DATA_DIRECTORY_TXT.Length; k++)
                    {
                        lvitem = new ListViewItem();
                        lvitem.Group = lvGroup;
                        lvitem.Text = pe.DATA_DIRECTORY_TXT[k];
                        string s1 = "";
                        for (int j = 0; j < pe.DATA_DIRECTORY_LEN[k]; j++)
                        {
                            s1 += pe_byte_array[i_index].ToString("X2");
                            i_index++;
                        }
                        s1 = CPub.HexReversal(s1);
                        lvitem.SubItems.Add(CPub.insertStrStepN(s1.Trim(), 4, " "));    //每4字节用空格分隔
                        lvitem.SubItems.Add(pe.DATA_DIRECTORY_OTH[k]);                  //数据说明
                        lvitem.Tag = s1.Trim();
                        lv_info.Items.Add(lvitem);

                        /*
                        if (lvitem.Text == "VirtualAddress")
                        {
                            pe.DATA_DIRECTORY[i].VirtualAddress = Convert.ToUInt32(CPub.HexReversal(s1), 16);
                            //CDebug.Send(Convert.ToString(pe.DATA_DIRECTORY[i].VirtualAddress, 16));
                        }
                        else if (lvitem.Text == "Size")
                        {
                            pe.DATA_DIRECTORY[i].Size = Convert.ToUInt32(CPub.HexReversal(s1), 16);
                            //CDebug.Send(Convert.ToString(pe.DATA_DIRECTORY[i].Size, 16));
                        }
                        */
                    }
                }

            }
            catch (Exception ex)
            {
                CDebug.SendError(ex.ToString());
            }
            CDebug.ExitMethod("解析数据目录");
        }

        /// <summary>
        /// 解析区块表
        /// </summary>
        private void getSectionHeader()
        {
            CDebug.EnterMethod("解析区块表");
            try
            {

                DWORD i_index = pe.SECTION_HEADER_START + 8;    //偏移8字节
                CDebug.Send("SECTION_HEADER 起始位置：" + i_index.ToString("X"));

                DWORD d_index = pe.SECTION_HEADER_START + 8;
                pe.SECTION_HEADER = new CPE._IMAGE_SECTION_HEADER[pe.FILE_HEADER.NumberOfSections];     //实例化区块表数组对象
                for (int i = 0; i < pe.FILE_HEADER.NumberOfSections; i++)
                {
                    //CDebug.Send(i.ToString() + "," + d_index.ToString("X"));
                    pe.SECTION_HEADER[i] = new CPE._IMAGE_SECTION_HEADER();                             //实例化数组元素
                    CPub.BytesToStuct(pe_byte_array, pe.SECTION_HEADER[i], (Int32)d_index);
                    d_index += (DWORD)Marshal.SizeOf(pe.SECTION_HEADER[i]);


                }

                //将区块名称加入树目录
                if (tv_pe.Nodes[3].Nodes.Count == 0)
                {
                    for (int i = 0; i < pe.FILE_HEADER.NumberOfSections;i++ )
                    {
                        string s1 = "[" + (i + 1) + "] " + System.Text.Encoding.Default.GetString(pe.SECTION_HEADER[i].Name);
                        TreeNodePE node1 = new TreeNodePE(s1, 3, 3);
                        node1.Tag = 4000;
                        node1.i_typ = 4000;
                        node1.i_index = i;
                        tv_pe.Nodes[3].Nodes.Add(node1);
                    }
                }

                ListViewGroup lvGroup = new ListViewGroup("SECTION_HEADER");
                lv_info.Groups.Add(lvGroup);
                ListViewItem lvitem = null;
                for (int i = 0; i < pe.FILE_HEADER.NumberOfSections; i++)
                {

                    for (int k = 0; k < pe.SECTION_HEADER_TXT.Length; k++)
                    {
                        lvitem = new ListViewItem();
                        lvitem.Text = pe.SECTION_HEADER_TXT[k];
                        string s1 = "";         //区段名称、最大长度为8个字节
                        string s_name = "";
                        bool b_end = false;     //区段名是否结束
                        for (int j = 0; j < pe.SECTION_HEADER_LEN[k]; j++)
                        {
                            if (pe_byte_array[i_index] == 0) b_end = true;                              //字符串结束
                            if (k == 0 && !b_end) s_name += Convert.ToChar(pe_byte_array[i_index]);     //name 显示字符串 循环到结尾位置、直接退出
                            s1 += pe_byte_array[i_index].ToString("X2");
                            i_index++;
                        }

                        //显示全部 或 单个区块数据
                        if (tvNode.i_typ == 4000 && tvNode.i_index != i) continue;
                            
                        if (k == 0)
                        {
                            lvGroup = new ListViewGroup(s_name);
                            lv_info.Groups.Add(lvGroup);
                        }
                        lvitem.Group = lvGroup;
                        if (k != 0) s1 = CPub.HexReversal(s1);                                                  //反转字符串
                        lvitem.SubItems.Add(CPub.insertStrStepN(s1.Trim(), 4, " "));                            //每4字节用空格分隔
                        string sOth = pe.SECTION_HEADER_OTH[k];                                                 //说明
                        if (k == 0) sOth = s_name + " //" + sOth;                                               //说明 显示字符串
                        lvitem.SubItems.Add(sOth);                                                              //结构体说明
                        lvitem.Tag = s1.Trim();
                        lv_info.Items.Add(lvitem);
                    }
                }

                //pe.DATA_DIRECTORY_START = Convert.ToString(i_index, 16);         // 起始位置
            }
            catch (Exception ex)
            {
                CDebug.SendError(ex.ToString());
            }
            CDebug.ExitMethod("解析区块表");
        }

        /// <summary>
        /// 解析输入表
        /// </summary>
        private void getImportDescriptor()
        {
            CDebug.EnterMethod("解析输入表");
            try
            {
                pe.IMPORT_DESCRIPTOR_START = pe.DATA_DIRECTORY[CPE.IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress;     //输入表起始位置
                DWORD l1 = pe.IMPORT_DESCRIPTOR_START;
                if (l1==0)
                {
                    CDebug.Send("没有输入表");
                    CDebug.ExitMethod("解析输入表");
                    return;
                }
                DWORD dw_offset = 0;       //在文件中的偏移
                for (int i = pe.FILE_HEADER.NumberOfSections-1; i >= 0; i--)
                {
                    if (l1 >= pe.SECTION_HEADER[i].VirtualAddress)      //查找输入表所在区块，输入表起始位置大于等于区块起始位置，小于下一区块起始位置
                    {
                        dw_offset = pe.SECTION_HEADER[i].VirtualAddress - pe.SECTION_HEADER[i].PointerToRawData;   //计算偏移地址
                        CDebug.Send("i=" + i.ToString() + ": " + Convert.ToString(pe.SECTION_HEADER[i].VirtualAddress, 16) + "-" 
                            + Convert.ToString(pe.SECTION_HEADER[i].PointerToRawData, 16) + "=" + Convert.ToString(dw_offset, 16) 
                            + ", SIZE=" + Convert.ToString(pe.DATA_DIRECTORY[CPE.IMAGE_DIRECTORY_ENTRY_IMPORT].Size, 16));
                        break;
                    }
                }
                DWORD i_index = l1 - dw_offset;                                                                     //计算偏移地址
                CDebug.Send("输入表起始位置：" + l1.ToString("X") + "-" + dw_offset.ToString("X") + "=" + i_index.ToString("X"));

                #region 给结构体赋值
                DWORD i_end = i_index + pe.DATA_DIRECTORY[CPE.IMAGE_DIRECTORY_ENTRY_IMPORT].Size;
                DWORD d_index = l1 - dw_offset;
                DWORD i_count = pe.DATA_DIRECTORY[CPE.IMAGE_DIRECTORY_ENTRY_IMPORT].Size / (DWORD)Marshal.SizeOf(new CPE._IMAGE_IMPORT_DESCRIPTOR());
                CDebug.Send("结构体个数：" + i_count);
                pe.IMPORT_DESCRIPTOR = new CPE._IMAGE_IMPORT_DESCRIPTOR[i_count];
                for (int i = 0; i < i_count; i++)
                {
                    pe.IMPORT_DESCRIPTOR[i] = new CPE._IMAGE_IMPORT_DESCRIPTOR();
                    CPub.BytesToStuct(pe_byte_array, pe.IMPORT_DESCRIPTOR[i], (Int32)d_index);
                    d_index += (DWORD)Marshal.SizeOf(pe.IMPORT_DESCRIPTOR[i]);
                }
                #endregion

                /*
                //通过反射遍历结构体
                for (int i = 0; i < i_count; i++)
                {
                    Type type = typeof(CPE._IMAGE_IMPORT_DESCRIPTOR);
                    foreach (FieldInfo mi in type.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic))
                    {
                        Object Value = mi.GetValue(pe.IMPORT_DESCRIPTOR[i]);
                        CDebug.Send(mi.Name + "=" + Convert.ToString((DWORD)Value, 16) + ",type=" + mi.FieldType.Name);
                        
                    }
                }
                */

                #region 树目录显示
                if (tv_pe.Nodes[4].Nodes.Count == 0)
                {
                    string s2 = "";
                    for (int i = 0; i < pe.IMPORT_DESCRIPTOR.Length;i++ )
                    {
                        s2 = "";
                        TreeNodePE node1 = new TreeNodePE();
                        node1.ImageIndex = 3;
                        node1.SelectedImageIndex = 3;
                        //解析dll名称
                        long l4 = pe.IMPORT_DESCRIPTOR[i].Name;
                        if (l4 != 0)
                        {
                            long l3 = l4 - dw_offset;                              //通过偏移计算字符串位置
                            //CDebug.Send(Convert.ToString(l4, 16) + "-" + Convert.ToString(l2, 16) + "=" + Convert.ToString(l3, 16));
                            while (l3 < f_Len && l3 > 0 && pe_byte_array[l3] != 0)
                            {
                                s2 += Convert.ToChar(pe_byte_array[l3]);
                                l3++;
                            }
                            node1.Text = s2;
                        }
                        else
                        {
                            if (s2 == "") break;        //dll名为空，停止解析
                        }

                        if (pe.IMPORT_DESCRIPTOR[i].OriginalFirstThunk != 0)
                        {
                            DWORD d_index2 = pe.IMPORT_DESCRIPTOR[i].OriginalFirstThunk - dw_offset;
                            CPE._IMAGE_THUNK_DATA32  THUNK_DATA = new CPE._IMAGE_THUNK_DATA32();
                            CPub.BytesToStuct(pe_byte_array, THUNK_DATA, (Int32)d_index2);
                            while (THUNK_DATA.AddressOfData != 0)
                            {
                                //最高位第32位为0时显示函数名，为1时为序号输入
                                if (THUNK_DATA.AddressOfData >> 31 == 0)
                                {
                                    DWORD d_name_adr = THUNK_DATA.AddressOfData - dw_offset;
                                    if (d_name_adr > 0 && d_name_adr < f_Len)   //下标是否越界
                                    {
                                        //Hint 函数在驻留dll的输出表中的序号
                                        string s3 = pe_byte_array[d_name_adr].ToString("X2");
                                        d_name_adr++;
                                        s3 += pe_byte_array[d_name_adr].ToString("X2");
                                        d_name_adr++;

                                        string s4 = "";
                                        while (pe_byte_array[d_name_adr] != 0)
                                        {
                                            s4 += Convert.ToChar(pe_byte_array[d_name_adr]);
                                            d_name_adr++;
                                        }
                                        TreeNodePE node2 = new TreeNodePE();
                                        node2.ImageIndex = 3;
                                        node2.SelectedImageIndex = 3;
                                        node2.Text = "[" + s3 + "] " + s4;  //函数名称
                                        node1.Nodes.Add(node2);
                                    }
                                }
                                else
                                {
                                    //低31位为序号
                                    DWORD d_name_adr = THUNK_DATA.AddressOfData - 0x80000000;

                                    TreeNodePE node2 = new TreeNodePE();
                                    node2.ImageIndex = 3;
                                    node2.SelectedImageIndex = 3;
                                    node2.Text = "[-] 序号：" + d_name_adr.ToString("X4");  //函数序号
                                    node1.Nodes.Add(node2);
                                }


                                d_index2 += 4;
                                CPub.BytesToStuct(pe_byte_array, THUNK_DATA, (Int32)d_index2);  
                            } 
                        }

                        if (pe.IMPORT_DESCRIPTOR[i].FirstThunk != 0)
                        {
                            DWORD d_index2 = pe.IMPORT_DESCRIPTOR[i].FirstThunk - dw_offset;
                            CPE._IMAGE_THUNK_DATA32 THUNK_DATA = new CPE._IMAGE_THUNK_DATA32();
                            CPub.BytesToStuct(pe_byte_array, THUNK_DATA, (Int32)d_index2);
                            while (THUNK_DATA.AddressOfData != 0)
                            {
                                DWORD d_name_adr = THUNK_DATA.AddressOfData - dw_offset;
                                if (d_name_adr > 0 && d_name_adr < f_Len)   //下标越界
                                {
                                    //Hint 函数在驻留dll的输出表中的序号
                                    string s3 = pe_byte_array[d_name_adr].ToString("X2");
                                    d_name_adr++;
                                    s3 += pe_byte_array[d_name_adr].ToString("X2");
                                    d_name_adr++;

                                    string s4 = "";
                                    while (pe_byte_array[d_name_adr] != 0)
                                    {
                                        s4 += Convert.ToChar(pe_byte_array[d_name_adr]);
                                        d_name_adr++;
                                    }
                                    TreeNodePE node2 = new TreeNodePE();
                                    node2.ImageIndex = 3;
                                    node2.SelectedImageIndex = 3;
                                    node2.Text = "[" + s3 + "] " + s4; //函数名称
                                    Boolean b_name = false;
                                    foreach (TreeNodePE node_temp in node1.Nodes)
                                    {
                                        if (node2.Text == node_temp.Text)
                                        {
                                            b_name = true;
                                            break;
                                        }
                                    }
                                    if (!b_name) node1.Nodes.Add(node2);
                                }

                                d_index2 += 4;
                                CPub.BytesToStuct(pe_byte_array, THUNK_DATA, (Int32)d_index2);
                            }
                        }
                        //tv_info.Nodes.Add(node1);
                        tv_pe.Nodes[4].Nodes.Add(node1);
                    }
                }
                #endregion

                #region 列表显示
                if (lv_info.Visible)
                {
                    ListViewGroup lvGroup = new ListViewGroup("Import Descriptor");
                    lv_info.Groups.Add(lvGroup);
                    ListViewItem lvitem = null;

                    int i_No = 0;
                    while (i_index < i_end)
                    {
                        string s1 = "";
                        string s2 = "";
                        for (int k = 0; k < pe.IMPORT_DESCRIPTOR_TXT.Length; k++)
                        {
                            lvitem = new ListViewItem();
                            lvitem.Text = pe.IMPORT_DESCRIPTOR_TXT[k];
                            s1 = "";
                            for (int j = 0; j < pe.IMPORT_DESCRIPTOR_LEN[k]; j++)
                            {
                                //if (k == 0) s2 += Convert.ToChar(pe_byte_array[i_index]);         //name 显示字符串
                                s1 += pe_byte_array[i_index].ToString("X2");
                                i_index++;
                            }

                            lvitem.Group = lvGroup;
                            lvitem.SubItems.Add(CPub.insertStrStepN(s1.Trim(), 4, " "));            //每4字节用空格分隔                        
                            if (k == 0)
                            {
                                i_No++;
                                lvitem.SubItems.Add(i_No.ToString());                               //序号
                            }
                            //给对象赋值
                            switch (pe.IMPORT_DESCRIPTOR_TXT[k])
                            {
                                case "Name":                                              //dll名称
                                    #region 解析dll名称
                                    try
                                    {
                                        long l4 = pe.IMPORT_DESCRIPTOR[i_No - 1].Name;
                                        if (l4 != 0)
                                        {
                                            long l3 = l4 - dw_offset;                              //通过偏移计算字符串位置
                                            //CDebug.Send(Convert.ToString(l4, 16) + "-" + Convert.ToString(l2, 16) + "=" + Convert.ToString(l3, 16));
                                            while (l3 < f_Len && l3 > 0 && pe_byte_array[l3] != 0)
                                            {
                                                s2 += Convert.ToChar(pe_byte_array[l3]);
                                                l3++;
                                            }
                                            lvitem.SubItems.Add(s2);
                                        }
                                        else
                                        {
                                            if (s2 == "") break;        //dll名为空，停止解析
                                        }
                                    }
                                    catch (Exception ex)
                                    {
                                        CDebug.SendError(ex.ToString());
                                    }
                                    #endregion
                                    break;
                            }

                            lvitem.Tag = s1.Trim();
                            lv_info.Items.Add(lvitem);

                        }

                        if (s2 == "") break;
                    }
                }
                #endregion
                //pe.DATA_DIRECTORY_START = Convert.ToString(i_index, 16);                      // 起始位置
            }
            catch (Exception ex)
            {
                CDebug.SendError(ex.ToString());
            }
            CDebug.ExitMethod("解析输入表");
        }

        /// <summary>
        /// 解析输出表
        /// </summary>
        private void getExportDirectory()
        {
            CDebug.EnterMethod("解析输出表");
            try
            {
                tv_info.Nodes.Clear();
                tv_pe.Nodes[5].Nodes.Clear();

                pe.EXPORT_DIRECTORY_START = pe.DATA_DIRECTORY[CPE.IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress;     //输出表起始位置
                DWORD l1 = pe.EXPORT_DIRECTORY_START;
                if (l1 == 0)
                {
                    CDebug.Send("没有输出表");
                    CDebug.ExitMethod("解析输出表");
                    return;
                }
                DWORD dw_offset = 0;       //在文件中的偏移
                for (int i = pe.FILE_HEADER.NumberOfSections - 1; i >= 0; i--)
                {
                    if (l1 >= pe.SECTION_HEADER[i].VirtualAddress)      //查找输入表所在区块，输入表起始位置大于等于区块起始位置，小于下一区块起始位置
                    {
                        dw_offset = pe.SECTION_HEADER[i].VirtualAddress - pe.SECTION_HEADER[i].PointerToRawData;   //计算偏移地址
                        CDebug.Send("i=" + i.ToString() + ": " + Convert.ToString(pe.SECTION_HEADER[i].VirtualAddress, 16) + "-"
                            + Convert.ToString(pe.SECTION_HEADER[i].PointerToRawData, 16) + "=" + Convert.ToString(dw_offset, 16)
                            + ", SIZE=" + Convert.ToString(pe.DATA_DIRECTORY[CPE.IMAGE_DIRECTORY_ENTRY_EXPORT].Size, 16));
                        break;
                    }
                }
                DWORD i_index = l1 - dw_offset;                                                                     //计算偏移地址
                CDebug.Send("输出表起始位置：" + l1.ToString("X") + "-" + dw_offset.ToString("X") + "=" + i_index.ToString("X"));

                #region 给结构体赋值
                DWORD i_end = i_index + pe.DATA_DIRECTORY[CPE.IMAGE_DIRECTORY_ENTRY_EXPORT].Size;
                DWORD d_index = l1 - dw_offset;
                DWORD i_count = pe.DATA_DIRECTORY[CPE.IMAGE_DIRECTORY_ENTRY_EXPORT].Size / (DWORD)Marshal.SizeOf(new CPE._IMAGE_EXPORT_DIRECTORY());
                CDebug.Send("数量：" + i_count);
                CPub.BytesToStuct(pe_byte_array, pe.EXPORT_DIRECTORY, (Int32)d_index);
                d_index += (DWORD)Marshal.SizeOf(pe.EXPORT_DIRECTORY);

                #endregion

                #region 树目录显示
                if (tv_pe.Nodes[5].Nodes.Count == 0)
                {
                    TreeNodePE node1 = new TreeNodePE();
                    node1.ImageIndex = 3;
                    node1.SelectedImageIndex = 3;
                    string sDllName = "";
                    DWORD d_index2 = pe.EXPORT_DIRECTORY.Name - dw_offset;
                    while (d_index2 > 0 && d_index2 < f_Len && pe_byte_array[d_index2] != 0)
                    {
                        sDllName += Convert.ToChar(pe_byte_array[d_index2]);
                        d_index2++;
                    }
                    node1.Text = sDllName;

                    Int32 i_fun_count = (Int32)pe.EXPORT_DIRECTORY.NumberOfFunctions;    //EAT条码数量
                    Int32 i_nam_count = (Int32)pe.EXPORT_DIRECTORY.NumberOfNames;        //ENT条码数量
                    string[] sFun = new string[i_fun_count];                            //函数序号
                    string[] sNam = new string[i_nam_count];                            //名称
                    string[] s_Index = new string[i_nam_count];                         //序号与名称的对应关系

                    d_index2 = pe.EXPORT_DIRECTORY.AddressOfFunctions - dw_offset;
                    CDebug.Send("函数数量：" + i_fun_count + " 地址：" + d_index2.ToString("X"));
                    for (int j = 0; j < i_fun_count; j++)
                    {
                        for (int k = 0; k < 4; k++)
                        {
                            sFun[j] += pe_byte_array[d_index2].ToString("X2");
                            d_index2++;
                        }
                        sFun[j] = CPub.HexReversal(sFun[j]);        //反转16进制
                    }

                    d_index2 = pe.EXPORT_DIRECTORY.AddressOfNames - dw_offset;
                    CDebug.Send("函数名称数量：" + i_nam_count + " 地址：" + d_index2.ToString("X"));
                    for (int j = 0; j < i_nam_count; j++)
                    {
                        string s1 = "";
                        for (int k = 0; k < 4; k++)
                        {
                            s1 += pe_byte_array[d_index2].ToString("X2");
                            d_index2++;
                        }
                        s1 = CPub.HexReversal(s1);              //反转16进制

                        DWORD dw1 = Convert.ToUInt32(s1, 16) - dw_offset;   //函数名存放地址

                        while (dw1 > 0 && dw1 < f_Len && pe_byte_array[dw1] != 0)
                        {
                            sNam[j] += Convert.ToChar(pe_byte_array[dw1]);
                            dw1++;
                        }
                        //CDebug.Send(j.ToString() + ": " + sNam[j]);
                    }

                    //函数与名称对应关系
                    d_index2 = pe.EXPORT_DIRECTORY.AddressOfNameOrdinals - dw_offset;
                    CDebug.Send("序号数组地址：" + d_index2.ToString("X"));
                    for (int j = 0; j < i_nam_count; j++)
                    {
                        for (int k = 0; k < 2; k++)
                        {
                            s_Index[j] += pe_byte_array[d_index2].ToString("X2");
                            d_index2++;
                        }
                        s_Index[j] = CPub.HexReversal(s_Index[j]);                      //反转16进制

                        DWORD dw1 = Convert.ToUInt32(s_Index[j], 16);
                        if (dw1 > 0 && Convert.ToUInt32(sFun[(Int32)dw1], 16) > 0)      //地址为0的函数为无效函数
                        {
                            TreeNodePE node2 = new TreeNodePE();
                            node2.ImageIndex = 3;
                            node2.SelectedImageIndex = 3;
                            node2.Text = "[" + sFun[(Int32)dw1] + "] " + sNam[j];

                            if (i_fun_count > dw1) node1.Nodes.Add(node2);
                        }

                    }

                    /*
                    //函数名称入库
                    CSQLite ado1 = new CSQLite(Application.StartupPath + "\\APIDoc.db");
                    DataSet ds_APIDoc = ado1.sel1("SELECT DLL,API,[INDEX],ADDR FROM APIDoc");
                    int i_id = ado1.getNewID("APIDoc", "ID");
                    StringBuilder strSQL = new StringBuilder();
                    for (int j = 0; j < i_nam_count; j++)
                    {
                        DWORD dw1 = Convert.ToUInt32(s_Index[j], 16);
                        string sADDR = sFun[(Int32)dw1];
                        DataRow[] drs = ds_APIDoc.Tables[0].Select("DLL='" + sDllName.Replace("'","''") + "' AND API='" + sNam[j].Replace("'","''") + "'");     //在结果集中查找
                        if (drs.Length == 0)
                        {
                            strSQL.Append("INSERT INTO APIDoc(ID,[INDEX],DLL,API,ADDR) VALUES(" + Convert.ToString(i_id) + ",'" + dw1 + "','" + sDllName.Replace("'", "''") + "','" + sNam[j].Replace("'", "''") + "','" + sADDR + "');\n");
                            i_id++;
                        }
                        /*  //操作过多导致程序运行变慢
                        else
                        {
                            DataRow[] drs1 = ds_APIDoc.Tables[0].Select("DLL='" + sDllName + "' AND (API IS NULL OR [INDEX] IS NULL OR ADDR IS NULL)");
                            if (drs1.Length > 0)
                            {
                                //更新API序号
                                DataRow[] drs2 = ds_APIDoc.Tables[0].Select("DLL='" + sDllName + "' AND API='" + sNam[j] + "' AND [INDEX] IS NULL");
                                if (drs2.Length > 0)
                                {
                                    strSQL.Append("UPDATE APIDoc SET [Index]='" + dw1 + "' WHERE DLL='" + sDllName + "' AND API='" + sNam[j] + "';\n");
                                }
                                //更新API地址
                                DataRow[] drs3 = ds_APIDoc.Tables[0].Select("DLL='" + sDllName + "' AND API='" + sNam[j] + "' AND ADDR IS NULL");
                                if (drs3.Length > 0)
                                {
                                    strSQL.Append("UPDATE APIDoc SET ADDR='" + sADDR + "' WHERE DLL='" + sDllName + "' AND API='" + sNam[j] + "';\n");
                                }
                                //更新API名称
                                DataRow[] drs4 = ds_APIDoc.Tables[0].Select("DLL='" + sDllName + "' AND [INDEX]='" + dw1 + "' AND API IS NULL");
                                if (drs3.Length > 0)
                                {
                                    strSQL.Append("UPDATE APIDoc SET API='" + sNam[j] + "' WHERE DLL='" + sDllName + "' AND [INDEX]='" + dw1 + "';\n");
                                }
                            }
                        } // -/

                    }
                    CDebug.Send("sql语句长度：" + strSQL.Length.ToString());
                    if (strSQL.Length > 0) ado1.cmd1(strSQL.ToString());
                    
                    //tv_info.Nodes.Add(node1);
                    tv_pe.Nodes[5].Nodes.Add(node1);
                     * */
                }
                #endregion
            }
            catch (System.Exception ex)
            {
                CDebug.SendError(ex.ToString());
            }
            CDebug.ExitMethod("解析输出表");
        }

        /// <summary>
        /// 解析资源
        /// </summary>
        private void getResourceDirectory()
        {
            CDebug.EnterMethod("解析资源");
            try
            {

                pe.RESOURCE_DIRECTORY_START = pe.DATA_DIRECTORY[CPE.IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress;     //资源起始位置
                DWORD l1 = pe.RESOURCE_DIRECTORY_START;
                if (l1 == 0)
                {
                    CDebug.Send("没有资源");
                    CDebug.ExitMethod("解析资源");
                    return;
                }
                DWORD dw_offset = 0;       //在文件中的偏移
                for (int i = pe.FILE_HEADER.NumberOfSections - 1; i >= 0; i--)
                {
                    if (l1 >= pe.SECTION_HEADER[i].VirtualAddress)      //查找输入表所在区块，输入表起始位置大于等于区块起始位置，小于下一区块起始位置
                    {
                        dw_offset = pe.SECTION_HEADER[i].VirtualAddress - pe.SECTION_HEADER[i].PointerToRawData;   //计算偏移地址 区块RVA - 文件中的偏移
                        CDebug.Send("i=" + i.ToString() + ": " + Convert.ToString(pe.SECTION_HEADER[i].VirtualAddress, 16) + "-"
                            + Convert.ToString(pe.SECTION_HEADER[i].PointerToRawData, 16) + "=" + Convert.ToString(dw_offset, 16)
                            + ", SIZE=" + Convert.ToString(pe.DATA_DIRECTORY[CPE.IMAGE_DIRECTORY_ENTRY_RESOURCE].Size, 16));
                        break;
                    }
                }
                DWORD i_index = l1 - dw_offset;                         //获得在文件中的地址                                              //计算偏移地址
                CDebug.Send("资源起始位置：" + l1.ToString("X") + "-" + dw_offset.ToString("X") + "=" + i_index.ToString("X"));

                #region 给结构体赋值
                DWORD i_end = i_index + pe.DATA_DIRECTORY[CPE.IMAGE_DIRECTORY_ENTRY_RESOURCE].Size;
                DWORD d_index = l1 - dw_offset; //偏移

                //资源开始位置
                //getRes(tv_info, d_index, 1,dw_offset);
                if (tv_pe.Nodes[6].Nodes.Count == 0)
                    getRes(tv_pe.Nodes[6], d_index, 1, dw_offset);

                #endregion


            }
            catch (System.Exception ex)
            {
                CDebug.SendError(ex.ToString());
            }
            CDebug.ExitMethod("解析资源");
        }

        /// <summary>
        /// 递归解析资源目录及资源
        /// </summary>
        /// <param name="node1">treeview or treenode</param>
        /// <param name="i_start">起始地址</param>
        /// <param name="i_Level">目录层数</param>
        /// <param name="dw_offset">偏移</param>
        private void getRes(object node1,DWORD i_start,int i_Level,DWORD dw_offset)
        {
            //CDebug.EnterMethod("解析资源");
            try
            {
                //资源开始位置
                DWORD dw_res_start = pe.DATA_DIRECTORY[CPE.IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress;
                CPE._IMAGE_RESOURCE_DIRECTORY res1 = new CPE._IMAGE_RESOURCE_DIRECTORY();
                CPub.BytesToStuct(pe_byte_array, res1, (Int32)i_start);
                i_start += (DWORD)Marshal.SizeOf(res1);
                int i_count = res1.NumberOfIdEntries + res1.NumberOfNamedEntries; //使用名字的资源条目的个数 + 使用ID的资源条目的个数
                //CDebug.Send("下一级节点个数：" + i_count);
                for (int i = 0; i < i_count; i++)
                {
                    //CDebug.Send("地址：" + i_start.ToString("X"));
                    CPE._IMAGE_RESOURCE_DIRECTORY_ENTRY res_entry1 = new CPE._IMAGE_RESOURCE_DIRECTORY_ENTRY();
                    CPub.BytesToStuct(pe_byte_array, res_entry1, (Int32)i_start);
                    i_start += (DWORD)Marshal.SizeOf(res_entry1);                      //下一个结构体起始位置

                    //CDebug.Send(res_enter1.Name.ToString("X"));
                    TreeNodePE node2 = new TreeNodePE();
                    if (i_Level == 1)       //第一层为资源类型
                    {
                        node2.ImageIndex = 3;
                        node2.SelectedImageIndex = 3;
                        if (res_entry1.Name >> 31 == 1)
                        {
                            node2.Text = (res_entry1.Name - 0x80000000).ToString(); //显示ID
                        }
                        else
                        {
                            if (res_entry1.Name < pe.RESOURCE_DIRECTORY_CAPTION.Length)
                                node2.Text = pe.RESOURCE_DIRECTORY_CAPTION[res_entry1.Name];
                            else
                                node2.Text = res_entry1.Name.ToString();
                        }
                        
                        if (res_entry1.OffsetToData >> 31 == 1)
                        {
                            //指向下一级节点
                            DWORD i_start2 =dw_res_start + res_entry1.OffsetToData - 0x80000000 - dw_offset;  //指向下一层目录起始地址 
                            //CDebug.Send("下一级目录起始地址：" + i_start2.ToString("X"));
                            getRes(node2, i_start2, 2, dw_offset);
                        }
                        else
                        {
                            //指向Image_resource_directory_entry结构
                            DWORD i_start2 = dw_res_start + res_entry1.OffsetToData - dw_offset;  //指向下一层目录起始地址 
                            CPE._IMAGE_RESOURCE_DATA_ENTRY res_data = new CPE._IMAGE_RESOURCE_DATA_ENTRY();
                            CPub.BytesToStuct(pe_byte_array, res_data, (Int32)i_start2);
                            node2.Text += "[RAV:" + res_data.OffsetToData.ToString("X") + "]"
                                + "[OFFSET:" + (res_data.OffsetToData - dw_offset).ToString("X") + "]"
                                + "[SIZE:" + res_data.Size.ToString("X") + "]";
                        }
                    }
                    else if (i_Level == 2)  //第二层为资源名称
                    {
                        node2.ImageIndex = 3;
                        node2.SelectedImageIndex = 3;
                        DWORD i_start2 = 0;
                        if (res_entry1.Name >> 31 == 1)
                        {
                            i_start2 = dw_res_start + res_entry1.Name - 0x80000000 - dw_offset;    //减去第一位
                            if (i_start2 > 0 && i_start2 < f_Len)
                            {
                                CPE._IMAGE_RESOURCE_DIR_STRING_U strU = new CPE._IMAGE_RESOURCE_DIR_STRING_U();
                                string s1 = pe_byte_array[i_start2].ToString("X2") + pe_byte_array[i_start2 + 1].ToString("X2");
                                i_start2++;
                                i_start2++;
                                s1 = CPub.HexReversal(s1);
                                strU.Length = Convert.ToUInt16(s1, 16);

                                //char[] cpara = System.Text.Encoding.Default.GetChars(pe_byte_array);    //byte[]转char[]
                                //string s2 = new string(cpara, (Int32)i_start2, strU.Length);
                                string s2 = "";
                                //次代码需要改写 System.Text.Encoding.Default.GetString(byte[] bytes)
                                for (int j = 0; j < strU.Length;j++ )
                                {
                                    s2 += Convert.ToChar(pe_byte_array[j * 2 + i_start2]);
                                }
                                
                                strU.NameString = s2;
                                node2.Text = s2;
                            }

                        }
                        else
                        {
                            node2.Text = res_entry1.Name.ToString();
                        }

                        if (res_entry1.OffsetToData >> 31 == 1) //还有下一层
                        {
                            //指向下一级节点
                            i_start2 = dw_res_start + res_entry1.OffsetToData - 0x80000000 - dw_offset;  //指向下一层目录起始地址 
                            //CDebug.Send("下一级目录起始地址：" + i_start2.ToString("X"));
                            getRes(node2, i_start2, 3, dw_offset);
                        }
                        else
                        {
                            //指向Image_resource_directory_entry结构
                            i_start2 = dw_res_start + res_entry1.OffsetToData - dw_offset;  //指向下一层目录起始地址 
                            CPE._IMAGE_RESOURCE_DATA_ENTRY res_data = new CPE._IMAGE_RESOURCE_DATA_ENTRY();
                            CPub.BytesToStuct(pe_byte_array, res_data, (Int32)i_start2);
                            node2.Text += "[RAV:" + res_data.OffsetToData.ToString("X") + "]"
                                + "[OFFSET:" + (res_data.OffsetToData - dw_offset).ToString("X") + "]"
                                + "[SIZE:" + res_data.Size.ToString("X") + "]";
                        }

                    }
                    else if (i_Level == 3)   //第三层为代码页编号
                    {
                        node2.ImageIndex = 3;
                        node2.SelectedImageIndex = 3;
                        DWORD i_start2 = 0;
                        if (res_entry1.Name >> 31 == 1)
                        {
                            i_start2 = dw_res_start + res_entry1.Name - 0x80000000 - dw_offset;    //减去第一位
                            if (i_start2 > 0 && i_start2 < f_Len)
                            {
                                CPE._IMAGE_RESOURCE_DIR_STRING_U strU = new CPE._IMAGE_RESOURCE_DIR_STRING_U();
                                string s1 = pe_byte_array[i_start2].ToString("X2") + pe_byte_array[i_start2 + 1].ToString("X2");
                                i_start2++;
                                i_start2++;
                                s1 = CPub.HexReversal(s1);
                                strU.Length = Convert.ToUInt16(s1, 16);

                                //char[] cpara = System.Text.Encoding.Default.GetChars(pe_byte_array);    //byte[]转char[]
                                //string s2 = new string(cpara, (Int32)i_start2, strU.Length);
                                string s2 = "";
                                for (int j = 0; j < strU.Length; j++)
                                {
                                    s2 += Convert.ToChar(pe_byte_array[j * 2 + i_start2]);
                                }

                                strU.NameString = s2;
                                node2.Text = s2;
                            }

                        }
                        else
                        {
                            node2.Text = res_entry1.Name.ToString();
                        }

                        if (res_entry1.OffsetToData >> 31 == 1) //还有下一层
                        {
                            //指向下一级节点
                            i_start2 = dw_res_start + res_entry1.OffsetToData - 0x80000000 - dw_offset;  //指向下一层目录起始地址 
                            CDebug.Send("下一级目录起始地址：" + i_start2.ToString("X"));
                            getRes(node2, i_start2, 4, dw_offset);
                        }
                        else
                        {
                            //指向Image_resource_directory_entry结构
                            i_start2 = dw_res_start + res_entry1.OffsetToData - dw_offset;  //指向下一层目录起始地址 
                            CPE._IMAGE_RESOURCE_DATA_ENTRY res_data = new CPE._IMAGE_RESOURCE_DATA_ENTRY();
                            CPub.BytesToStuct(pe_byte_array, res_data, (Int32)i_start2);
                            node2.Text += "[RAV:" + res_data.OffsetToData.ToString("X") + "]"
                                + "[OFFSET:" + (res_data.OffsetToData - dw_offset).ToString("X") + "]"
                                + "[SIZE:" + res_data.Size.ToString("X") + "]";
                        }
                    }

                    if (node1 is TreeView) ((TreeView)node1).Nodes.Add(node2);
                    if (node1 is TreeNodePE) ((TreeNodePE)node1).Nodes.Add(node2);
                }
            }
            catch (System.Exception ex)
            {
                CDebug.SendError(ex.ToString());
            }
            //CDebug.ExitMethod("解析资源");
        }

        /// <summary>
        /// 点击数列表、切换数据
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void tv_pe_AfterSelect(object sender, TreeViewEventArgs e)
        {
            if (tv_pe.SelectedNode == null) return;
            if (f_Len == 0) return;

            tvNode = (TreeNodePE)tv_pe.SelectedNode;                    //获取选中的节点
            int i_tag = Convert.ToInt32(tvNode.Tag);
            tv_pe_index = i_tag;
            
            lv_info.Items.Clear();                          //清除listview中的已有数据
            lv_info.Visible = true;
            tv_info.Visible = false;
            tboxHex.Text = "";
            tboxHex.Visible = false;

            switch (i_tag)
            {
                case 100:       //ms-dos头
                    getDosHeader();                         //解析DOS_Header
                    break;
                case 200:       //pe头
                    getFileHeader();                        //解析File_Header

                    getOptionalHeader();                    //解析Optional_Header
                    break;
                case 300:       //pe头
                    getDataDirectory();                     //解析数据目录
                    break;
                case 400:       //区块表
                    getSectionHeader();                     //解析区块表
                    break;
                case 500:       //输入表
                    //lv_info.Visible = false;
                    //tv_info.Visible = true;
                    //tboxHex.Visible = true;
                    //splitter3.Visible = true;
                    getImportDescriptor();                  //解析输入表
                    break;
                case 600:       //输出表
                    //lv_info.Visible = false;
                    //tv_info.Visible = true;
                    //tboxHex.Visible = true;
                    //splitter3.Visible = true;
                    getExportDirectory();
                    break;
                case 700:       //资源
                    lv_info.Visible = false;
                    tv_info.Visible = true;
                    getResourceDirectory();
                    break;
                case 4000:
                    getSectionHeader();                     //显示单个区块表
                    break;
            }
        }

        /// <summary>
        /// 读取api说明文件（html文件） 导入数据库
        /// </summary>
        private void readHtmlFile()
        {
            CDebug.EnterMethod("读取文件");
            FolderBrowserDialog fbdlg = new FolderBrowserDialog();
            fbdlg.SelectedPath = "D:\\Temp\\api";
            if (fbdlg.ShowDialog() == DialogResult.OK)
            {
                /*
                CSQLite ado1 = new CSQLite(Application.StartupPath + "\\APIDoc.db");
                DataSet ds_APIDoc = ado1.sel1("SELECT DLL,API,Length(OTH) V FROM APIDoc");
                StringBuilder strSQL = new StringBuilder();
                DirectoryInfo dinf = new DirectoryInfo(fbdlg.SelectedPath);
                foreach (FileInfo finf in dinf.GetFiles())
                {
                    //CDebug.Send(finf.FullName);
                    string sNam = finf.Name;
                    sNam = sNam.Substring(0, sNam.IndexOf("."));
                    DataRow[] drs = ds_APIDoc.Tables[0].Select("API='" + sNam + "' OR API='" + sNam + "'+'A' OR API='" + sNam + "'+'W'");
                    if (drs.Length > 0 && drs[0]["V"].ToString() == string.Empty)
                    {
                        string s1 = "";
                        for (int i = 0; i < drs.Length; i++)
                        {
                            s1 += drs[i]["API"].ToString() + ", ";
                        }
                        CDebug.Send(sNam + " -> " + s1 + " " + drs.Length);
                        FileStream fs = File.Open(finf.FullName, FileMode.Open, FileAccess.Read);
                        int i1 = (int)finf.Length;
                        byte[] b1 = new byte[i1];
                        int nBytesRead = fs.Read(b1, 0, i1);
                        fs.Close();

                        string s2 = System.Text.Encoding.Default.GetString(b1);
                        string s3 = CPub.findStrBetween(s2, "<", ">");
                        while (s3 != "")
                        {
                            s2 = s2.Replace("<" + s3 + ">", "");
                            s3 = CPub.findStrBetween(s2, "<", ">");
                        }
                        s2 = s2.Replace("&nbsp;", "");
                        s2 = s2.Replace("\r\n\r\n", "\r\n");
                        s2 = s2.Replace("'", "''");

                        for (int i = 0; i < drs.Length; i++)
                        {
                            strSQL.Append("UPDATE APIDoc SET OTH='" + s2 + "' WHERE API='" + drs[i]["API"].ToString() + "' ;\n");
                        }

                    }
                    else
                    {
                        CDebug.Send(sNam + " 没有找到");
                    }
                }
                ado1.cmd1(strSQL.ToString());
                 * */
            }
            CDebug.ExitMethod("读取文件");
        }

        /// <summary>
        /// 点击树目录，显示函数信息
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void tv_info_AfterSelect(object sender, TreeViewEventArgs e)
        {
            /*
            if (tv_info.SelectedNode != null)
            {
                TreeNodePE node = (TreeNodePE)tv_info.SelectedNode;
                string sTxt = node.Text;
                CSQLite ado1 = new CSQLite(Application.StartupPath + "\\APIDoc.db");
                switch (tv_pe_index)
                {
                    case 500:       //输入表
                        if (sTxt.IndexOf(" ") == -1) break;
                        string s1 = sTxt.Split(' ')[1];
                        tboxHex.Text = s1 + "\n";
                        DataSet ds1 = ado1.sel1("SELECT * FROM APIDoc WHERE Length(OTH)>0 AND API='" + s1 + "'");
                        if (!ado1.dsIsNull(ds1))
                        {
                            tboxHex.Text += ds1.Tables[0].Rows[0]["Oth"].ToString();
                        }
                        break;
                    case 600:       //输出表
                        if (sTxt.IndexOf(" ") == -1) break;
                        string s2 = sTxt.Split(' ')[1];
                        tboxHex.Text = s2 + "\n";
                        //CSQLite ado1 = new CSQLite(Application.StartupPath + "\\APIDoc.db");
                        DataSet ds2 = ado1.sel1("SELECT * FROM APIDoc WHERE Length(OTH)>0 AND API='" + s2 + "'");
                        if (!ado1.dsIsNull(ds2))
                        {
                            tboxHex.Text += ds2.Tables[0].Rows[0]["Oth"].ToString();
                        }
                        break;
                }

            }
            */
        }

        private void refDataView()
        {
            if (f_Len == 0 || panel1.Width < 10) return;
            B.Dispose();
            g.Dispose();
            B = new Bitmap(panel1.Width, panel1.Height);
            g = Graphics.FromImage(B);

            Int32 i_panel_width = panel1.Width - 30;
            float f_scale = (float)pe.OPTIONAL_HEADER.SizeOfImage / (float)i_panel_width;      //文件装入内存中的长度 与 panel长度的比值

            List<int> ldata = new List<int>();
            List<int> lblock = new List<int>();
            int i1 = 0;
            int ic = 0;
            for (int i = 0; i < pe.SECTION_HEADER.Length; i++)
            {
                Int32 iw1 = (Int32)(pe.SECTION_HEADER[i].VirtualSize / f_scale);
                Int32 iw2 = (Int32)(pe.SECTION_HEADER[i].SizeOfRawData / f_scale);

                ldata.Add(iw1);
                lblock.Add(iw2);
            }

            for (int i = 0; i < ldata.Count; i++)
            {
                int iw = 50;
                if(ldata[i] < iw)
                {
                    int i2 = iw - ldata[i];
                    ldata[i] = iw;
                    

                    for (int j = 0;j<ldata.Count;j++)
                    {
                        if(ldata[j] - i2 >=iw)
                        {
                            ldata[j] -= i2;
                            lblock[j] -= i2;
                            break;
                        }
                    }
                }
                if (lblock[i] < ldata[i]) lblock[i] = ldata[i];
            }

            // 绘制区块表分布缩略图
            int i_left = 0;
            for (int i = 0; i < pe.SECTION_HEADER.Length; i++)
            {
                Button btn1;
                if (lstBtn.Count > i && lstBtn[i] != null)
                {
                    btn1 = lstBtn[i];
                }
                else
                {
                    btn1 = new Button();
                    lstBtn.Add(btn1);
                }
                string s1 = System.Text.Encoding.Default.GetString(pe.SECTION_HEADER[i].Name);
                //Int32 i_left = (Int32)(pe.SECTION_HEADER[i].VirtualAddress / f_scale);
                //Int32 i_width = (Int32)(pe.SECTION_HEADER[i].VirtualSize / f_scale);
                int i_width = ldata[i];                

                btn1.Text = s1;
                btn1.Parent = panel1;
                btn1.Top = 1;
                btn1.Height = 20;
                btn1.Left = i_left;
                btn1.Width = i_width;
                btn1.Show();

                int i_w2 = lblock[i];
                
                
                //在文件中的对齐尺寸
                //Int32 i_f_size = (Int32)(pe.SECTION_HEADER[i].SizeOfRawData / f_scale);
                if (i_w2 - i_width > 5)
                {
                    Rectangle rect = new Rectangle(i_left + i_width, 2, i_w2 - i_width - 1, 18);
                    //Pen pen = new Pen(Color.Green);
                    //g.DrawRectangle(pen, rect);
                    Brush brush = new SolidBrush(Color.Gray);
                    g.FillRectangle(brush, rect);
                }
                i_left += i_w2;
                /*
                if (i == 0)                                   //绘制pe头长度
                {
                    if (i_left > 5)
                    {
                        SolidBrush blueBrush = new SolidBrush(Color.Red);
                        Rectangle rect2 = new Rectangle(0, 2, i_left - 1, 17);
                        //g.FillRectangle(blueBrush, rect);
                        Pen pen2 = new Pen(Color.Red);
                        g.DrawRectangle(pen2, rect2);
                    }
                }
                */
            }

            //释放不用的资源
            for (int i = pe.SECTION_HEADER.Length; i < lstBtn.Count;i++ )
            {
                lstBtn[i].Hide();
            }

            //Graphics g2 = panel1.CreateGraphics();
            //g2.DrawImage(B, 0, 0);
        }

        private void FPEMain_Paint(object sender, PaintEventArgs e)
        {

        }

        private void panel1_Paint(object sender, PaintEventArgs e)
        {
            Graphics g2 = panel1.CreateGraphics();
            g2.DrawImage(B, 0, 0);
        }

        private void FPEMain_Resize(object sender, EventArgs e)
        {
            refDataView();      //重绘区段缩略图
            this.Refresh();
        }
    }



    public static class JTBOX
    {
        /// <summary>
        /// 注册插件
        /// </summary>
        /// <param name="node1"></param>
        /// <param name="list1"></param>
        /// <returns></returns>
        public static bool RegPlug(List<Form> list1,ImageList imgLst)
        {
            try
            {
                FPEMain f1 = new FPEMain();
                list1.Add(f1);

                imgLst.Images[list1.Count - 1] = f1.imageList2.Images[0];
            }
            catch (System.Exception ex)
            {
                CDebug.SendError(ex.ToString());
                return false;
            }
            return true;
        }
    }
}
